package com.mes.cloud.service;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.mes.cloud.api.dto.request.BatchDeleteRequest;
import com.mes.cloud.api.dto.request.employee.BindRoleRequest;
import com.mes.cloud.api.dto.request.employee.EmployeeIsMainRoleRequest;
import com.mes.cloud.api.dto.request.employee.RolePageListRequest;
import com.mes.cloud.api.dto.request.role.BindEmployeeRequest;
import com.mes.cloud.api.dto.request.role.EmployeePageListRequest;
import com.mes.cloud.api.dto.response.SysEmployeeRoleDto;
import com.mes.cloud.api.dto.response.employee.RoleListDto;
import com.mes.cloud.api.dto.response.role.RoleEmployeeDto;
import com.mes.cloud.exception.BaseException;
import com.mes.cloud.common.CommPager;
import com.mes.cloud.common.JsonResult;
import com.mes.cloud.constant.Constants;
import com.mes.cloud.dao.BaseEmployeeDao;
import com.mes.cloud.dao.SysEmployeeRoleDao;
import com.mes.cloud.dao.SysRoleDao;
import com.mes.cloud.entity.BaseEmployee;
import com.mes.cloud.entity.SysEmployeeLog;
import com.mes.cloud.entity.SysEmployeeRole;
import com.mes.cloud.entity.SysRole;
import com.mes.cloud.entity.vo.employee.RoleVo;
import com.mes.cloud.entity.vo.role.EmployeeVo;
import com.mes.cloud.enums.HttpStatusEnum;
import com.mes.cloud.util.DateUtil;
import com.mes.cloud.util.UserUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 角色用户关联表
 *
 * @author wxm
 * @version 2019-08-02 15:02:43
 * @email xiaomin.wu1@pactera.com
 */
@Service
public class SysEmployeeRoleService {

    private SysEmployeeRoleDao sysEmployeeRoleDao;

    private IPKeyGenerator iPKeyGenerator;

    private BaseEmployeeDao baseEmployeeDao;

    private LogService logService;

    //角色Dao
    private SysRoleDao sysRoleDao;

    @Autowired
    public SysEmployeeRoleService(SysEmployeeRoleDao sysEmployeeRoleDao, IPKeyGenerator iPKeyGenerator,
                                  BaseEmployeeDao baseEmployeeDao, LogService logService, SysRoleDao sysRoleDao) {
        this.sysEmployeeRoleDao = sysEmployeeRoleDao;
        this.iPKeyGenerator = iPKeyGenerator;
        this.baseEmployeeDao = baseEmployeeDao;
        this.logService = logService;
        this.sysRoleDao = sysRoleDao;
    }

    /**
     * 角色界面查看员工列表
     *
     * @param employeePageListPageRequest
     * @return
     */
    public JsonResult<CommPager<RoleEmployeeDto>> employeePageList(EmployeePageListRequest employeePageListPageRequest) {
        Page<SysEmployeeRoleDto> page = PageHelper.startPage(employeePageListPageRequest.getCurrentPage(), employeePageListPageRequest.getPageSize());
        List<EmployeeVo> employeeVoList = sysEmployeeRoleDao.employeePageList(employeePageListPageRequest);
        List<RoleEmployeeDto> employeeListDtoList = new ArrayList<>();
        RoleEmployeeDto roleEmployeeDto = null;
        for (EmployeeVo employeeVo : employeeVoList) {
            roleEmployeeDto = new RoleEmployeeDto();
            BeanUtils.copyProperties(employeeVo, roleEmployeeDto);
            employeeListDtoList.add(roleEmployeeDto);
        }
        CommPager<RoleEmployeeDto> pageList = new CommPager<>(page, employeeListDtoList);
        JsonResult<CommPager<RoleEmployeeDto>> jsonResult = new JsonResult<CommPager<RoleEmployeeDto>>();
        jsonResult.setMsg(HttpStatusEnum.OK.getMessage()).setCode(HttpStatusEnum.OK.getCode()).setData(pageList);
        return jsonResult;
    }

    /**
     * 员工界面查看角色列表
     *
     * @param rolePageListRequest
     * @return
     */
    public JsonResult<CommPager<RoleListDto>> rolePageList(RolePageListRequest rolePageListRequest) {
        Page<RoleVo> page = PageHelper.startPage(rolePageListRequest.getCurrentPage(), rolePageListRequest.getPageSize());
        List<RoleVo> roleVoList = sysEmployeeRoleDao.rolePageList(rolePageListRequest);
        List<RoleListDto> roleListDtoList = new ArrayList<>();
        RoleListDto roleListDto = null;
        for (RoleVo roleVo : roleVoList) {
            roleListDto = new RoleListDto();
            BeanUtils.copyProperties(roleVo, roleListDto);
            roleListDtoList.add(roleListDto);
        }
        CommPager<RoleListDto> pageList = new CommPager<>(page, roleListDtoList);
        JsonResult<CommPager<RoleListDto>> jsonResult = new JsonResult<CommPager<RoleListDto>>();
        jsonResult.setMsg(HttpStatusEnum.OK.getMessage()).setCode(HttpStatusEnum.OK.getCode()).setData(pageList);
        return jsonResult;
    }

    /**
     * 角色增加员工
     *
     * @param bindEmployeeRequest
     * @return
     */
    public JsonResult bindEmployee(BindEmployeeRequest bindEmployeeRequest) {
        JsonResult jsonResult = new JsonResult();
        //获取角色已有员工
        SysEmployeeRole sysEmployeeRoleParam = new SysEmployeeRole();
        sysEmployeeRoleParam.setRoleId(bindEmployeeRequest.getRoleId());
        //未删除状态
        sysEmployeeRoleParam.setDelFlag(Constants.DEL_FLAG_NO);
        List<SysEmployeeRole> existSysEmployeeRoleList = sysEmployeeRoleDao.select(sysEmployeeRoleParam);

        //新增员工已有角色
        Set<String> idList = deleteExistEmployeeId(existSysEmployeeRoleList, bindEmployeeRequest.getIds());

        //组装员工角色对象
        List<SysEmployeeRole> sysEmployeeRoleList = roleGeneratorSysEmployeeRole(idList, bindEmployeeRequest.getRoleId());
        if (CollectionUtils.isEmpty(sysEmployeeRoleList)) {
            return jsonResult.setCode(HttpStatusEnum.REF_EXIST.getCode()).setMsg(HttpStatusEnum.REF_EXIST.getMessage());
        }
        //批量插入
        int count = sysEmployeeRoleDao.batchInsert(sysEmployeeRoleList);
        if (count > 0) {
            jsonResult.setMsg(HttpStatusEnum.OK.getMessage()).setCode(HttpStatusEnum.OK.getCode());
        } else {
            throw new BaseException(HttpStatusEnum.FAIL.getCode(),HttpStatusEnum.FAIL.getMessage());
        }
        return jsonResult;
    }

    /**
     * 员工添加角色
     *
     * @param bindRoleRequest
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public JsonResult bindRole(BindRoleRequest bindRoleRequest) {
        JsonResult jsonResult = new JsonResult();
        //获取员工已有角色
        SysEmployeeRole sysEmployeeRoleParam = new SysEmployeeRole();
        sysEmployeeRoleParam.setEmployeeId(bindRoleRequest.getEmployeeId());
        //未删除状态
        sysEmployeeRoleParam.setDelFlag(Constants.DEL_FLAG_NO);
        List<SysEmployeeRole> existSysEmployeeRoleList = sysEmployeeRoleDao.select(sysEmployeeRoleParam);

        //新增角色剔除员工已有角色
        Set<String> idList = deleteExistRoleId(existSysEmployeeRoleList, bindRoleRequest.getIds());

        //组装员工角色对象
        List<SysEmployeeRole> sysEmployeeRoleList = generatorSysEmployeeRole(idList, bindRoleRequest.getEmployeeId());
        if (CollectionUtils.isEmpty(sysEmployeeRoleList)) {
            return jsonResult.setCode(HttpStatusEnum.REF_EXIST.getCode()).setMsg(HttpStatusEnum.REF_EXIST.getMessage());
        }
        //批量插入
        int count = sysEmployeeRoleDao.batchInsert(sysEmployeeRoleList);
        if (count > 0) {
            // 如果没有主要角色，将第一条角色设置为主要角色
            BaseEmployee baseEmployee = baseEmployeeDao.selectByPrimaryKey(bindRoleRequest.getEmployeeId());
            if(baseEmployee!= null && StringUtils.isEmpty(baseEmployee.getMainRoleId())){
                //第一条设置为主要角色
                SysEmployeeRole first = sysEmployeeRoleList.get(0);
                SysEmployeeRole mainRole = new SysEmployeeRole();
                mainRole.setId(first.getId());
                mainRole.setRoleMainFlag(Constants.ROLE_MAINFLAG);
                sysEmployeeRoleDao.updateRoleMainFlag(bindRoleRequest.getEmployeeId());
                sysEmployeeRoleDao.updateByPrimaryKeySelective(mainRole);

                BaseEmployee employUpdate = new BaseEmployee();
                employUpdate.setId(bindRoleRequest.getEmployeeId());
                // 设置主角色
                SysRole sysRole = sysRoleDao.selectByPrimaryKey(first.getRoleId());
                employUpdate.setMainRoleId(sysRole.getId());
                employUpdate.setMainRoleName(sysRole.getRoleName());
                baseEmployeeDao.updateByPrimaryKeySelective(employUpdate);
            }
            jsonResult.setMsg(HttpStatusEnum.OK.getMessage()).setCode(HttpStatusEnum.OK.getCode());
            this.insertLog(bindRoleRequest.getEmployeeId(), Constants.ADD_LINK_TO_ROLE);
        } else {
            throw new BaseException(HttpStatusEnum.FAIL.getCode(),HttpStatusEnum.FAIL.getMessage());
        }
        return jsonResult;
    }

    /**
     * 组装SysEmployeeRole关联数据
     *
     * @param idList     角色ID集合
     * @param employeeId 员工ID
     * @return
     */
    private List<SysEmployeeRole> generatorSysEmployeeRole(Set<String> idList, String employeeId) {
        List<SysEmployeeRole> sysEmployeeRoleList = new ArrayList<SysEmployeeRole>();
        if (CollectionUtils.isEmpty(idList)) {
            return sysEmployeeRoleList;
        }
        SysEmployeeRole sysEmployeeRoleTemp = null;
        for (String id : idList) {
            sysEmployeeRoleTemp = generatorSysEmployeeRole(employeeId, id);
            sysEmployeeRoleList.add(sysEmployeeRoleTemp);
        }
        return sysEmployeeRoleList;
    }

    /**
     * 组装SysEmployeeRole关联数据
     *
     * @param idList 员工ID集合
     * @param roleId 角色ID
     * @return
     */
    private List<SysEmployeeRole> roleGeneratorSysEmployeeRole(Set<String> idList, String roleId) {
        List<SysEmployeeRole> sysEmployeeRoleList = new ArrayList<SysEmployeeRole>();
        if (idList == null) {
            return sysEmployeeRoleList;
        }
        SysEmployeeRole sysEmployeeRoleTemp = null;
        for (String id : idList) {
            sysEmployeeRoleTemp = generatorSysEmployeeRole(id, roleId);
            sysEmployeeRoleList.add(sysEmployeeRoleTemp);
        }
        return sysEmployeeRoleList;
    }

    /**
     * 组织一个SysEmployeeRole
     *
     * @param employeeId
     * @param roleId
     * @return
     */
    private SysEmployeeRole generatorSysEmployeeRole(String employeeId, String roleId) {
        SysEmployeeRole sysEmployeeRoleTemp = new SysEmployeeRole();
        sysEmployeeRoleTemp.setId(iPKeyGenerator.getGenerateKey());
        sysEmployeeRoleTemp.setEmployeeId(employeeId);
        sysEmployeeRoleTemp.setRoleId(roleId);
        sysEmployeeRoleTemp.setUpdateDateStr(DateUtil.updateDateStr());
        sysEmployeeRoleTemp.setCreateBy(UserUtil.getCreateByName());
        sysEmployeeRoleTemp.setUpdateBy(UserUtil.getUpdateByName());
        sysEmployeeRoleTemp.setCreateByNo(UserUtil.getCreateByNo());
        sysEmployeeRoleTemp.setUpdateByNo(UserUtil.getUpdateByNo());
        return sysEmployeeRoleTemp;
    }

    /**
     * 剔除idList存在 existSysEmployeeRoleList中的id
     *
     * @param existSysEmployeeRoleList 数据库中已经存在的员工角色关联关系
     * @param idList                   需要添加的角色ID
     * @return
     */
    private Set<String> deleteExistRoleId(List<SysEmployeeRole> existSysEmployeeRoleList, Set<String> idList) {
        if (CollectionUtils.isEmpty(existSysEmployeeRoleList)) {
            return idList;
        }
        List<String> existIdList = new ArrayList<>();
        //员工已经拥有的角色ID存放到existIdList
        for (SysEmployeeRole sysEmployeeRole : existSysEmployeeRoleList) {
            existIdList.add(sysEmployeeRole.getRoleId());
        }
        return deleteExistId(existIdList, idList);
    }

    /**
     * 剔除idList存在 existSysEmployeeRoleList中的员工id
     *
     * @param existSysEmployeeRoleList 数据库中已经存在的员工角色关联关系
     * @param idList                   需要添加的员工id集合
     * @return
     */
    private Set<String> deleteExistEmployeeId(List<SysEmployeeRole> existSysEmployeeRoleList, Set<String> idList) {
        if (CollectionUtils.isEmpty(existSysEmployeeRoleList)) {
            return idList;
        }
        List<String> existIdList = new ArrayList<>();
        //员工已经拥有的角色ID存放到existIdList
        for (SysEmployeeRole sysEmployeeRole : existSysEmployeeRoleList) {
            existIdList.add(sysEmployeeRole.getEmployeeId());
        }
        return deleteExistId(existIdList, idList);
    }

    /**
     * existIdList  idList做比较,返回idList中不存在existIdList中的id
     *
     * @param existIdList
     * @param idList
     * @return
     */
    private Set<String> deleteExistId(List<String> existIdList, Set<String> idList) {
        Set<String> returnList = new HashSet<>();
        for (String id : idList) {
            //判断id是否存在existIdList列表中
            if (!existIdList.contains(id)) {
                returnList.add(id);
            }
        }
        return returnList;
    }

    /**
     * 批量移除关联关系
     *
     * @param batchDeleteRequest
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public JsonResult batchDelete(BatchDeleteRequest batchDeleteRequest) {
        JsonResult jsonResult = new JsonResult();
        int count = sysEmployeeRoleDao.batchDelete(batchDeleteRequest.getIds(), DateUtil.updateDateStr(), UserUtil.getEmployeeNo(),UserUtil.getName());
        if (count > 0) {
            //判断当前员工下是否有关联的岗位
            SysEmployeeRole employeeRole = new SysEmployeeRole();
            employeeRole.setEmployeeId(batchDeleteRequest.getEmployeeId());
            employeeRole.setDelFlag(Constants.DEL_FLAG_NO);
            int count1 = sysEmployeeRoleDao.selectCount(employeeRole);
            if(count1 == 0){
                //维护角色字段
                BaseEmployee baseEmployee = new BaseEmployee();
                baseEmployee.setId(batchDeleteRequest.getEmployeeId());
                baseEmployee.setMainRoleId("");
                baseEmployee.setMainRoleName("");
                baseEmployeeDao.updateByPrimaryKeySelective(baseEmployee);
            }
            jsonResult.setMsg(HttpStatusEnum.OK.getMessage()).setCode(HttpStatusEnum.OK.getCode());
            if (!StringUtils.isEmpty(batchDeleteRequest.getEmployeeId())) {
                this.insertLog(batchDeleteRequest.getEmployeeId(), Constants.REMOVE_LINK_TO_ROLE);
            } else {
                List<String> ids = batchDeleteRequest.getIds();
                for (String employeeRoleId : ids) {
                    SysEmployeeRole sysEmployeeRole = sysEmployeeRoleDao.selectByPrimaryKey(employeeRoleId);
                    this.insertLog(sysEmployeeRole.getEmployeeId(), Constants.REMOVE_LINK_TO_ROLE);
                }
            }
        } else {
            throw new BaseException(HttpStatusEnum.FAIL.getCode(),HttpStatusEnum.FAIL.getMessage());
        }
        return jsonResult;
    }


    /**
     * 描述  是否主角色
     *
     * @param employeeIsMainRoleRequest
     * @return com.shinho.tntframe.core.common.model.JsonResult
     * @author 郑样平
     * @date 2019/8/6 16:11
     */
    @Transactional(rollbackFor = Exception.class)
    public JsonResult isMainRole(EmployeeIsMainRoleRequest employeeIsMainRoleRequest) {
        JsonResult jsonResult = new JsonResult();
        SysEmployeeRole sysEmployeeRole = new SysEmployeeRole();
        sysEmployeeRole.setId(employeeIsMainRoleRequest.getId());
        sysEmployeeRole.setRoleMainFlag(Constants.ROLE_MAINFLAG);
        sysEmployeeRoleDao.updateRoleMainFlag(employeeIsMainRoleRequest.getEmployeeId());
        int count = sysEmployeeRoleDao.updateByPrimaryKeySelective(sysEmployeeRole);
        if (count > 0) {
            //修改员工角色
            BaseEmployee baseEmployee = new BaseEmployee();
            baseEmployee.setId(employeeIsMainRoleRequest.getEmployeeId());
            SysEmployeeRole employeeRole = sysEmployeeRoleDao.selectByPrimaryKey(employeeIsMainRoleRequest.getId());
            if (employeeRole.getRoleId() != null && !"".equals(employeeRole.getRoleId())) {
                SysRole sysRole = sysRoleDao.selectByPrimaryKey(employeeRole.getRoleId());
                baseEmployee.setMainRoleId(sysRole.getId());
                baseEmployee.setMainRoleName(sysRole.getRoleName());
            }
            baseEmployeeDao.updateByPrimaryKeySelective(baseEmployee);
            jsonResult.setMsg(HttpStatusEnum.OK.getMessage());
            jsonResult.setCode(HttpStatusEnum.OK.getCode());
            this.insertLog(employeeIsMainRoleRequest.getEmployeeId(), Constants.SET_MAIN_ROLE);
        } else {
            throw new BaseException(HttpStatusEnum.FAIL.getCode(),HttpStatusEnum.FAIL.getMessage());
        }
        return jsonResult;
    }

    /**
     * 描述 日志添加
     *
     * @param {sysEmployeeRole, logMessage]
     * @return int
     * @author 郑样平
     * @date 2019/8/8 10:07
     */
    int insertLog(String employeeId, String logMessage) {
        SysEmployeeLog sysEmployeeLog = new SysEmployeeLog();
        sysEmployeeLog.setEmployeeId(employeeId);
        sysEmployeeLog.setMenuCode(Constants.EMPLOYEE_MENU_CODE);
        sysEmployeeLog.setLog(logMessage);
        sysEmployeeLog.setId(iPKeyGenerator.getGenerateKey());
        sysEmployeeLog.setUpdateDateStr(DateUtil.updateDateStr());
        sysEmployeeLog.setCreateBy(UserUtil.getCreateByName());
        sysEmployeeLog.setUpdateBy(UserUtil.getUpdateByName());
        sysEmployeeLog.setCreateByNo(UserUtil.getCreateByNo());
        sysEmployeeLog.setUpdateByNo(UserUtil.getUpdateByNo());
        return logService.insertEmployeeLog(sysEmployeeLog);
    }

    /**
     * 批量插入关联关系
     *
     * @param sysEmployeeRoleList
     */
    public void batchAdd(List<SysEmployeeRole> sysEmployeeRoleList) {
        sysEmployeeRoleDao.batchInsert(sysEmployeeRoleList);
    }
}
